home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / misc / volume12 / ranlib / part01 next >
Encoding:
Text File  |  1990-04-25  |  14.4 KB  |  647 lines

  1. Newsgroups: comp.sources.misc
  2. subject: v12i014: replacement ranlib for SCO Xenix
  3. from: Steve.Bleazard@robobar.co.uk
  4. Sender: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
  5.  
  6. Posting-number: Volume 12, Issue 14
  7. Submitted-by: Steve.Bleazard@robobar.co.uk
  8. Archive-name: ranlib/part01
  9.  
  10. This is a replacement ranlib(CP) for SCO Xenix.  It's needed when
  11. the library to be ranlib'ed has externals longer than 40 characters
  12. because the SCO ranlib barfs on them, although their ld(CP) appears
  13. to be quite happy with these long externals.
  14.  
  15. This program was created with GCC and G++ users in mind.  They should
  16. save this file if they see it posted.
  17.  
  18. Freely redistributable, but copyrighted.
  19.  
  20. #! /bin/sh
  21. # This is a shell archive, meaning:
  22. # 1. Remove everything above the #! /bin/sh line.
  23. # 2. Save the resulting text in a file.
  24. # 3. Execute the file with /bin/sh (not csh) to create the files:
  25. #    ranlib.c
  26. # This archive created: Wed Apr 25 15:04:27 1990
  27. export PATH; PATH=/bin:$PATH
  28. echo shar: extracting "'ranlib.c'" '(12748 characters)'
  29. if test -f 'ranlib.c'
  30. then
  31.     echo shar: will not over-write existing file "'ranlib.c'"
  32. else
  33. sed 's/^X//' << \SHAR_EOF > 'ranlib.c'
  34. Xstatic char rcsid[] = "@(#)$Header: /pdsrc/Local/RCS/ranlib.c,v 1.3 90/04/24 14:05:00 root Exp $";
  35. X
  36. X/*
  37. X * (C) Copyright 1990 Stephen A. Bleazard <Steve@Robobar.Co.Uk>
  38. X * 
  39. X * Permission is granted to redistribute this program and any derivatives
  40. X * thereof in source or binary form, for any purpose, including commercial
  41. X * use, provided that this copyright message is retained in the source code
  42. X * and is reproduced in full in any documentation that accompanies such
  43. X * redistribution.  Source code redistribution is encouraged, but is not
  44. X * mandatory.  The rcsid string above must be retained unmodified in any 
  45. X * redistributed binary.
  46. X *
  47. X * NO WARRANTY:  This software is licensed free of charge without any claim
  48. X * regarding its fitness for any purpose.  The Licensor cannot accept
  49. X * responsibility for any damage arising from the use or inability to use
  50. X * this software for any purpose.
  51. X */
  52. X
  53. X/*
  54. X * This is a replacement ranlib(CP) for SCO Xenix 386 System V.
  55. X * I have only tested it on Xenix 2.3.2 with the 2.3 Development System:
  56. X * your mileage may vary.
  57. X *
  58. X * This replacement ranlib is required when either:
  59. X *
  60. X *    a) you do not have a SCO Development system, but are hacking along
  61. X *       with PD, free, and GNU development tools,
  62. X *
  63. X * or    b) your library has external identifiers more than 40 characters
  64. X *       long, which is not uncommon if you happen to be using g++,
  65. X *       or indeed, most C++ compilers.
  66. X *
  67. X * Note that Xenix's ld seems perfectly happy to link objects with long
  68. X * identifiers, but the utilities like ranlib and nm barf on them under some
  69. X * circumstances which I am not going to bother to try to enumerate here
  70. X * or anywhere. ld -r does NOT cope with long identifiers.  You Lose.
  71. X *
  72. X * CAVEAT: The Xenix struct ar_hdr as defined in /usr/include/ar.h depends
  73. X * upon a Microsoft specific bodge (#pragma pack(2)) to force alignment
  74. X * of a long on a 2 byte boundary.  This is not a problem if you are
  75. X * compiling this ranlib with the Microsoft compiler.  Those wishing
  76. X * to use my port of GCC to Xenix will require a version patched to understand
  77. X * #pragma pack().  Such version can be identified when
  78. X *     $ /usr/local/lib/gcc-cc1 -version -quiet < /dev/null
  79. X * reports "#pragma pack() support included", which was not available with
  80. X * my original set of patches for GCC, and is in any case a non-compulsory
  81. X * compile-time option.
  82. X *
  83. X * Enjoy,
  84. X * Steve.
  85. X */
  86. X
  87. X/*
  88. X * $Log:    ranlib.c,v $
  89. X * Revision 1.3  90/04/24  14:05:00  root
  90. X * Removed annoying ANSI prototypes.
  91. X * fixed array memname size
  92. X * 
  93. X * Revision 1.2  90/04/23  07:56:07  root
  94. X * fixed argument to fseek at line 262.
  95. X * fixed -v message
  96. X * 
  97. X * Revision 1.1  90/04/23  07:50:18  root
  98. X * Initial revision
  99. X * 
  100. X */
  101. X
  102. X#include <stdio.h>
  103. X#include <varargs.h>
  104. X#include <string.h>
  105. X#include <ar.h>
  106. X
  107. Xtypedef struct symbol_t {
  108. X    char *name;
  109. X    long mempos;
  110. X    struct symbol_t *next;
  111. X} Symbol;
  112. X
  113. X#undef   i386
  114. X#define  XARMAG        0177545
  115. X#define  HDRSIZE    3
  116. X#define  NOERROR    0
  117. X#define  NODATA        1
  118. X#define  ILLSTRLEN    2
  119. X#define  EOFERR        3
  120. X#define  OMFNAMELENGTH  127
  121. X#define  MPUBDEF    0x90
  122. X#define  MPUB386    0x91
  123. X
  124. X
  125. XFILE *objfile;
  126. Xint objerror = NOERROR;
  127. Xint verbose = 0;    /* Say what we're doing */
  128. Xint trace = 0;        /* Say EVERYTHING we're doing */
  129. Xlong ar_lib_start;    /* where the actual lib stuff starts */
  130. XSymbol *symtable, *current_sym;
  131. X
  132. Xusage()
  133. X{
  134. X    fprintf(stderr, "usage: ranlib [-v] [-t] archive...\n");
  135. X}
  136. X
  137. Xvoid vmsg(fmt, va_alist)
  138. Xchar *fmt;
  139. Xva_dcl
  140. X{
  141. X    va_list args;
  142. X
  143. X    va_start(args);
  144. X    if (verbose)
  145. X        vfprintf(stderr, fmt, args);
  146. X    va_end(args);
  147. X}
  148. X
  149. Xvoid tmsg(fmt, va_alist)
  150. Xchar *fmt;
  151. Xva_dcl
  152. X{
  153. X    va_list args;
  154. X
  155. X    va_start(args);
  156. X    if (trace)
  157. X        vfprintf(stderr, fmt, args);
  158. X    va_end(args);
  159. X}
  160. X
  161. X
  162. Xvoid error(fmt, va_alist)
  163. Xchar *fmt;
  164. Xva_dcl
  165. X{
  166. X    va_list args;
  167. X
  168. X    va_start(args);
  169. X    fprintf(stderr, "error: ");
  170. X    vfprintf(stderr, fmt, args);
  171. X    va_end(args);
  172. X}
  173. X
  174. Xmain(argc, argv)
  175. Xint argc;
  176. Xchar **argv;
  177. X{
  178. X    int opt;
  179. X    extern optind;
  180. X
  181. X    if (argc < 2)
  182. X    {
  183. X        usage();
  184. X        exit(1);
  185. X    }
  186. X
  187. X    while ((opt = getopt(argc, argv, "vt")) != EOF)
  188. X    {
  189. X        switch (opt)
  190. X        {
  191. X        case 't':
  192. X            trace = 1;
  193. X            /*FALLTHROUGH*/
  194. X        case 'v':
  195. X            verbose = 1;
  196. X            vmsg("ranlib version:\n    %s\n", rcsid + 4);
  197. X            vmsg("Please report bugs to steve@robobar.co.uk.\n");
  198. X            break;
  199. X        case '?':
  200. X            usage();
  201. X            exit(1);
  202. X            break;
  203. X        }
  204. X    }
  205. X    tmsg("Options selected: %s%s\n", trace ? "-t " : "",
  206. X                     verbose ? "-v " : "");
  207. X
  208. X    for ( ; optind < argc; optind++ )
  209. X        ranlib(argv[optind]);
  210. X    exit(0);
  211. X}
  212. X
  213. Xint rdbytes(buff, count)
  214. Xchar *buff;
  215. Xint count;
  216. X{
  217. X    int retval;
  218. X
  219. X    if (retval = (fread(buff, 1, count, objfile) != count))
  220. X        objerror = EOFERR;
  221. X    return !retval;
  222. X}
  223. X
  224. Xint checkcnt(from, count)
  225. Xint *from, count;
  226. X{
  227. X    if ((*from - 1) < count)
  228. X    {
  229. X        objerror = NODATA;
  230. X        return 0;
  231. X    }
  232. X    *from -= count;
  233. X    return 1;
  234. X}
  235. X
  236. X
  237. Xlong rdvint(count, reclen)
  238. Xint count;
  239. Xint *reclen;
  240. X{
  241. X    long val = 0;
  242. X    unsigned char b;
  243. X    int i = 0;
  244. X
  245. X    if (!checkcnt(reclen, count))
  246. X        return -1;
  247. X    while (i < count)
  248. X    {
  249. X        rdbytes(&b, 1);
  250. X        val = val | ((long)b << ( 8 * i));
  251. X        i++;
  252. X    }
  253. X    return val;
  254. X}
  255. X
  256. Xlong rdoffset(i386, reclen)
  257. Xint i386;
  258. Xint *reclen;
  259. X{
  260. X    return rdvint(i386 ? 4 : 2, reclen);
  261. X}
  262. X
  263. Xunsigned int rdword(reclen)
  264. Xint *reclen;
  265. X{
  266. X    return (unsigned int)rdvint(2, reclen);
  267. X}
  268. X
  269. Xunsigned char rdbyte(reclen)
  270. Xint *reclen;
  271. X{
  272. X    unsigned char b;
  273. X
  274. X    if (!checkcnt(reclen, 1))
  275. X        return 0;
  276. X    rdbytes(&b, 1);
  277. X    return b;
  278. X}
  279. X
  280. Xunsigned int rdindex(reclen)
  281. Xint *reclen;
  282. X{
  283. X    unsigned char b, b1;
  284. X
  285. X    b = rdbyte(reclen);
  286. X    if (b < 128)
  287. X        return b;
  288. X    b1 = rdbyte(reclen);
  289. X    return (((unsigned int)b & 0x7f) << 8) + b1;
  290. X}
  291. X
  292. Xvoid rdomfstr(name, reclen)
  293. Xchar *name;
  294. Xint *reclen;
  295. X{
  296. X    unsigned char l;
  297. X
  298. X    l = rdbyte(reclen);
  299. X    if (l > OMFNAMELENGTH)
  300. X    {
  301. X        name[0] = '\0';
  302. X        objerror = ILLSTRLEN;
  303. X        fseek(objfile, (long) *reclen, 1);
  304. X        return;
  305. X    }
  306. X    if (!checkcnt(reclen, l))
  307. X    {
  308. X        name[0] = '\0';
  309. X        return;
  310. X    }
  311. X    rdbytes(name, l);  name[l] = '\0';
  312. X}
  313. X
  314. Xpubdef(i386, reclen, pos)
  315. Xint i386;
  316. Xint reclen;
  317. Xlong pos;
  318. X{
  319. X    unsigned int grpindex, segindex, framenum;
  320. X
  321. X    grpindex = rdindex(&reclen);
  322. X    segindex = rdindex(&reclen);
  323. X    if (grpindex == 0 && segindex == 0)
  324. X        framenum = rdword(&reclen);
  325. X
  326. X    while (reclen > 1)
  327. X    {
  328. X        char symbol_name[OMFNAMELENGTH+2];
  329. X        unsigned long offset; 
  330. X        int type;
  331. X
  332. X        rdomfstr(symbol_name, &reclen);
  333. X        offset = rdoffset(i386, &reclen);
  334. X        type = rdindex(&reclen);
  335. X        
  336. X        if (strncmp(symbol_name, "  ", 2) == 0)
  337. X        {
  338. X            tmsg("    skipping %s @ %#x\n", symbol_name, pos);
  339. X        }
  340. X        else
  341. X        {
  342. X
  343. X            tmsg("    adding %s @ %#x\n", symbol_name, pos);
  344. X            current_sym->next = (Symbol *)malloc(sizeof(Symbol));
  345. X            current_sym = current_sym->next;
  346. X            current_sym->name=(char *)malloc(strlen(symbol_name)+1);
  347. X            strcpy(current_sym->name, symbol_name);
  348. X            current_sym->mempos = pos;
  349. X        }
  350. X    }
  351. X    fseek(objfile, (long)reclen, 1);
  352. X}
  353. X
  354. X
  355. Xreadsymbols(fp, pos, size)
  356. XFILE *fp;
  357. Xlong pos, size;
  358. X{
  359. X    unsigned char buff[HDRSIZE+2];
  360. X    unsigned int reclen, rectype;
  361. X    long startpos;
  362. X    long ftell();
  363. X
  364. X    objfile = fp;  startpos = ftell(fp);  objerror = NOERROR;
  365. X
  366. X    while (((ftell(fp) - startpos) < size) && rdbytes(buff, HDRSIZE))
  367. X    {
  368. X        int rectype, reclen;
  369. X
  370. X        rectype = buff[0];
  371. X        reclen = buff[1] | ((int)buff[2] << 8);
  372. X        switch (rectype)
  373. X        {
  374. X            case MPUBDEF:
  375. X            pubdef(0, reclen, pos);
  376. X            break;
  377. X            case MPUB386:
  378. X            pubdef(1, reclen, pos);
  379. X            break;
  380. X            default:
  381. X            fseek(objfile, (long)reclen, 1);
  382. X            break;
  383. X        }
  384. X
  385. X        if (objerror != NOERROR)
  386. X        {
  387. X            error("invalid object file format\n");
  388. X            return;
  389. X        }
  390. X    }
  391. X}
  392. X
  393. Xcopy_old_ar_to_new(oldar_fp, newar_fp)
  394. XFILE *oldar_fp, *newar_fp;
  395. X{
  396. X    char buffer[BUFSIZ];
  397. X    int size;
  398. X
  399. X    fseek(oldar_fp, ar_lib_start, 0);
  400. X    while ((size = fread(buffer, 1, BUFSIZ, oldar_fp)) != 0)
  401. X        fwrite(buffer, 1, size, newar_fp);
  402. X}
  403. X
  404. Xtypedef Symbol *TablePtr;
  405. X
  406. Xstatic void merge(h1, t1, h2, t2, precedes)
  407. XTablePtr *h1, *t1, h2, t2;
  408. Xint (*precedes)();
  409. X{
  410. X    TablePtr saveTail, lop, prevlop;
  411. X
  412. X
  413. X#    define    invert    { TablePtr h;\
  414. X        h = lop;  lop = h2;  h2 = h; h = *t1;  *t1 = t2;  t2 = h; }
  415. X
  416. X    saveTail = t2->next;  lop = *h1;
  417. X    if ((*precedes)(h2, *h1))
  418. X    {
  419. X        invert
  420. X        *h1 = lop;
  421. X    }
  422. X    while (lop != *t1)
  423. X    {
  424. X        prevlop = lop;  lop = lop->next;
  425. X        if ((*precedes)(h2, lop))
  426. X        {
  427. X            prevlop->next = h2;
  428. X            invert
  429. X        }
  430. X    }
  431. X    (*t1)->next = h2;
  432. X    *t1 = t2;
  433. X    t2->next = saveTail;
  434. X}
  435. X
  436. Xstatic void localsort(maxseqlen, head, tail, precedes)
  437. Xint maxseqlen;
  438. XTablePtr *head, *tail;
  439. Xint (*precedes)();
  440. X{
  441. X    TablePtr nexthead, nexttail;
  442. X    int length;
  443. X
  444. X    length = 1;  *tail = *head;
  445. X    nexthead = (*tail)->next;
  446. X    while ((length < maxseqlen) && (nexthead != (TablePtr)NULL))
  447. X    {
  448. X        localsort(length, &nexthead, &nexttail, precedes);
  449. X        merge(head, tail, nexthead, nexttail, precedes);
  450. X        nexthead = (*tail)->next;
  451. X        length *= 2;
  452. X    }
  453. X}
  454. X
  455. Xvoid chainsort(head, precedes)
  456. XTablePtr *head;
  457. Xint (*precedes)();
  458. X{
  459. X    TablePtr finaltail;
  460. X
  461. X    if ((*head)->next != (TablePtr)NULL)
  462. X        localsort(0x7fff, head, &finaltail, precedes);
  463. X}
  464. X
  465. Xstatic int lesser(p1, p2)
  466. XTablePtr p1, p2;
  467. X{
  468. X    return (strcmp(p1->name, p2->name) < 0);
  469. X}
  470. X
  471. Xwrite_new_ar(oldar_fp, name, symtable)
  472. XFILE *oldar_fp;
  473. Xchar *name;
  474. XSymbol *symtable;
  475. X{
  476. X    static char template[] = "ranXXXXXX";
  477. X    char *path;
  478. X    Symbol *current;
  479. X    unsigned short symbolCount;
  480. X    long symtableSize, relocationFactor;
  481. X    FILE *fp;
  482. X    unsigned short magic = XARMAG;
  483. X    struct ar_hdr sym_hdr;
  484. X    long time();
  485. X    long ftell();
  486. X    
  487. X    mktemp(template);
  488. X    if (strchr(name, '/') != NULL)    /* Has a path */
  489. X    {
  490. X        char *p, *tmpname;
  491. X        
  492. X        tmpname = (char *)malloc(strlen(name)+1);
  493. X        strcpy(tmpname, name);
  494. X        p = strrchr(tmpname, '/');  *p = '\0';
  495. X        path = (char *)malloc(strlen(tmpname) + strlen(template) + 5);
  496. X        sprintf(path, "%s/%s", tmpname, template);
  497. X        free(tmpname);
  498. X    }
  499. X    else
  500. X    {
  501. X        path = (char *)malloc(strlen(template) + 5);
  502. X        sprintf(path, "./%s", template);
  503. X    }
  504. X    tmsg("creating %s\n", path);
  505. X
  506. X    chainsort(&symtable, lesser);
  507. X    current = symtable;  symbolCount = 0;  symtableSize = 2;
  508. X    while (current != NULL)
  509. X    {
  510. X        symtableSize += strlen(current->name) + 1 + 4;
  511. X        symbolCount++;
  512. X        tmsg("%s %#lx\n", current->name, current->mempos);
  513. X        current = current->next;
  514. X    }
  515. X    relocationFactor = symtableSize + sizeof(struct ar_hdr);
  516. X    if (relocationFactor & 1)
  517. X        relocationFactor++;
  518. X    relocationFactor -= ar_lib_start - 2;
  519. X    tmsg("adding %d symbols, %#lx(%ld) bytes, ", symbolCount, symtableSize, symtableSize);
  520. X    tmsg("relocation factor %#lx(%ld)\n", relocationFactor, relocationFactor);
  521. X
  522. X    current = symtable;
  523. X    while (current != NULL)
  524. X    {
  525. X        current->mempos += relocationFactor;
  526. X        tmsg("%s %#lx\n", current->name, current->mempos);
  527. X        current = current->next;
  528. X    }
  529. X
  530. X    if ((fp = fopen(path, "w")) == NULL)
  531. X    {
  532. X        fprintf(stderr,"ranlib: cannot open %s\n", path);
  533. X        exit(1);
  534. X    }
  535. X    fwrite((void *)&magic, sizeof(unsigned short), 1, fp);
  536. X    strncpy(sym_hdr.ar_name, "__.SYMDEF", 14);
  537. X    sym_hdr.ar_date = time((long *)0);
  538. X    sym_hdr.ar_uid = getuid();
  539. X    sym_hdr.ar_gid = getgid();
  540. X    sym_hdr.ar_mode = 0106644;
  541. X    sym_hdr.ar_size = symtableSize;
  542. X    fwrite((void *)&sym_hdr, sizeof(struct ar_hdr), 1, fp);
  543. X
  544. X    fwrite((void *)&symbolCount, sizeof(unsigned short), 1, fp);
  545. X    current = symtable;
  546. X    while (current != NULL)
  547. X    {
  548. X        unsigned char len;
  549. X
  550. X        len = (unsigned char)strlen(current->name);
  551. X        fwrite((void *)&len, 1, 1, fp);
  552. X        fwrite(current->name, len, 1, fp);
  553. X        fwrite((void *)¤t->mempos, sizeof(long), 1, fp);
  554. X        current = current->next;
  555. X    }
  556. X
  557. X    if (ftell(fp) & 1)
  558. X    {
  559. X        char nl = 0; 
  560. X        
  561. X        fwrite(&nl, 1, 1, fp);
  562. X    }
  563. X    copy_old_ar_to_new(oldar_fp, fp);
  564. X    fclose(fp);
  565. X
  566. X    unlink(name);
  567. X    link(path, name);
  568. X    unlink(path);
  569. X}
  570. X
  571. Xranlib(name)
  572. Xchar *name;
  573. X{
  574. X    FILE *fp;
  575. X    struct ar_hdr hdr;
  576. X    unsigned short magic = 0;
  577. X    long memoffset, ftell();
  578. X    int memcount;
  579. X
  580. X    if ((fp = fopen(name, "r")) == NULL)
  581. X    {
  582. X        fprintf(stderr,"ranlib: cannot open %s\n", name);
  583. X        exit(1);
  584. X    }
  585. X    vmsg("processing %s...", name);
  586. X    tmsg("\n");
  587. X
  588. X    if ((fread((void *)&magic, sizeof(unsigned short), 1, fp) != 1) ||
  589. X        (magic != XARMAG))
  590. X    {
  591. X        error("%s not in archive format\n", name);
  592. X        return;
  593. X    }
  594. X
  595. X    symtable = current_sym = (Symbol *)malloc(sizeof(Symbol));
  596. X    memoffset = ftell(fp);  memcount = 0;  ar_lib_start = 2;
  597. X
  598. X    while (fread((void *)&hdr, sizeof(struct ar_hdr), 1, fp) == 1)
  599. X    {
  600. X        char memname[15];
  601. X
  602. X        memname[14] = '\0';  strncpy(memname, hdr.ar_name, 14);
  603. X        vmsg("%s ", memname);
  604. X        tmsg("(pos = %#x, size = %ld)\n", memoffset, hdr.ar_size);
  605. X        if ((strcmp(memname, "__.SYMDEF") == 0) && !memcount)
  606. X        {
  607. X            ar_lib_start = memoffset + sizeof(struct ar_hdr)
  608. X                       + hdr.ar_size;
  609. X            if (ar_lib_start & 1)
  610. X                ar_lib_start++;
  611. X            tmsg("%s ", memname);
  612. X            vmsg("(skipped) ");
  613. X            tmsg("\n");
  614. X        }
  615. X        else
  616. X            readsymbols(fp, memoffset, hdr.ar_size);
  617. X
  618. X        memcount++;
  619. X        memoffset += sizeof(struct ar_hdr) + hdr.ar_size;
  620. X        if (memoffset & 1) memoffset++;
  621. X        fseek(fp, memoffset, 0);
  622. X    }
  623. X    current_sym->next = NULL;
  624. X    current_sym = symtable;  symtable = symtable->next;  free(current_sym);
  625. X
  626. X    write_new_ar(fp, name, symtable);
  627. X    fclose(fp);
  628. X
  629. X    for (current_sym = symtable; current_sym != NULL;)
  630. X    {
  631. X        Symbol *refuse;
  632. X
  633. X        refuse = current_sym;  current_sym = current_sym->next;
  634. X        free(refuse);
  635. X    }
  636. X    vmsg("\n");
  637. X}
  638. SHAR_EOF
  639. if test 12748 -ne "`wc -c < 'ranlib.c'`"
  640. then
  641.     echo shar: error transmitting "'ranlib.c'" '(should have been 12748 characters)'
  642. fi
  643. fi # end of overwriting check
  644. #    End of shell archive
  645. exit 0
  646.  
  647.